package com.base.starter.config.shiro;

import com.base.common.constant.UserConstants;
import com.base.common.result.ResultCode;
import com.base.domain.moudles.entity.User;
import com.base.service.UserService;
import com.base.starter.config.shiro.jwt.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

/**
 * @author zhou minghao
 * @date 2024/4/23
 * @description
 */
@Slf4j
@Component
public class MyRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    @Autowired
    private TokenService tokenService;

    /**
     * @Description: 权限认证
     * @Param: 身份信息
     * @return:
     * @Author: zhou minghao
     * @Date: 8:48 2024/4/23
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取请求主体
        Object primaryPrincipal = principals.getPrimaryPrincipal();
        //初始化存储用户信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //判断主体是否是User实例
        if (primaryPrincipal instanceof User) {
            User user = (User) primaryPrincipal;
            //判断获取出来的主体是不是空的
            if (ObjectUtils.isEmpty(user) || ObjectUtils.isEmpty(user.getId())) {
                return null;
            }
            //如果用户的角色是有值的就把值放到info中去
            if (!CollectionUtils.isEmpty(user.getRoles())) {
                info.setStringPermissions(null);
            }
        }
        return info;
    }

    /**
     * 身份认证
     * @param auth 身份信息
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        log.debug("===============Shiro身份认证开始============doGetAuthenticationInfo==========");
        Object token = auth.getCredentials();
        if (token == null) {
            throw new ExpiredCredentialsException("凭证为空!");
        }

        // 校验token有效性
        User user = tokenService.verificationToken((String) token);
        // 判断是否是被禁用的账号
        if (UserConstants.STATUS_TYPE_DISABLE.equals(user.getStatus())) {
            throw new DisabledAccountException(ResultCode.USER_ACCOUNT_DISABLE.getMsg());
        }
        return new SimpleAuthenticationInfo(user, token, getName());
    }
}
